home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
dpmigcc5.zip
/
RSX
/
SOURCE
/
DEB
/
DPMI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-27
|
7KB
|
269 lines
/*
** DPMI services for GNU_C
**
** (c) Rainer Schnitker 1994
*/
#include <stdio.h>
#define INLINE static inline
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct {
WORD lim_lo;
WORD base_lo;
BYTE base_mi,access,lim_hi,base_hi;
} DESCRIPTOR ;
typedef DESCRIPTOR *PDESCRIPTOR;
typedef struct { DWORD LargestFree;
DWORD MaxUnlockedPages;
DWORD MaxLockedPages;
DWORD AddressSpacePages;
DWORD UnlockedPages;
DWORD UnusedPages;
DWORD PhysicalPages;
DWORD FreeAddressSpacePages;
DWORD PagingFilePages; /* or partition size */
DWORD reserved[3];
} FREEMEMINFO ;
typedef FREEMEMINFO *PFREEMEMINFO;
/* descriptor makros */
#define DESC_BASE(d) (((((DWORD)d.base_hi<<8)|(DWORD)d.base_mi)<<16)|(DWORD)d.base_lo)
#define DESC_LIMIT(d) ((((DWORD)(d.lim_hi&15))<<16)|(DWORD)d.lim_lo)
#define GATE_OFFSET(d) (((((DWORD)d.base_hi<<8)|(DWORD)d.lim_hi)<<16)|(DWORD)d.lim_lo)
/* descriptor fields */
#define ACCESS_BIT 1
#define READ_BIT 2
#define WRITE_BIT 2
#define CONFIRMING_BIT 4
#define EXPAND_BIT 4
#define CODE_BIT 8
#define SEGMENT_BIT 16
#define PRESENT_BIT 128
#define AVL_BIT 16
#define DEFAULT_BIT 64
#define BIG_BIT 64
#define GRANULAR_BIT 128
#define DPL_MASK 96
#define TYPE_MASK 15
#define LIMIT_HI_MASK 15
#define APP_CODE_SEL 250 /* dpl=3 , read */
#define APP_DATA_SEL 242 /* dpl=3 ,write */
#define TYPE_CODE 10
#define TYPE_CONFIRM_CODE 14
#define TYPE_DATA 2
#define TYPE_EXPAND_DATA 6
#define TYPE_286TSS 1
#define TYPE_LDT 2
#define TYPE_BUSY286TSS 3
#define TYPE_286CALLGATE 4
#define TYPE_TASKGATE 5
#define TYPE_286INTGATE 6
#define TYPE_286TRAPGATE 7
#define TYPE_386TSS 9
#define TYPE_BUSY386TSS 11
#define TYPE_386CALLGATE 12
#define TYPE_386INTGATE 14
#define TYPE_386TRAPGATE 15
/* breakpoints-types */
#define BREAK_CODE 0x0001
#define BREAK_DATA_W1 0x0101
#define BREAK_DATA_RW1 0x0201
#define BREAK_DATA_W2 0x0102
#define BREAK_DATA_RW2 0x0202
#define BREAK_DATA_W4 0x0104
#define BREAK_DATA_RW4 0x0204
#define CHECKERR "jnc 1f\n\tmovl $-1, %0 \n\tjmp 2f \n\t1: \n\t"
#define CHECK_ERR_DPMI10 "jc 2f\n\t"
#define OKEAX0 "xorl %0, %0 \n\t2: \n\t"
INLINE int GetDescriptor(int sel, DESCRIPTOR *desc)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
: "=r" (_v)
: "b" (sel) , "D" ((long)desc) , "a" (0x0B)
);
return _v ;
}
INLINE int GetFreeMemInfo(FREEMEMINFO *info)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
: "=r" (_v)
: "D" ((long)info), "a" (0x500)
);
return _v ;
}
int is_emx_exe(void)
{
register int ver;
#ifdef __EMX__
/* os_version() uses ebx */
__asm__ ("pushl %ebx \n\t");
ver = __os_version();
__asm__ ("popl %ebx \n\t");
#else
__asm__ __volatile__(
"movb $0x30, %%ah \n\t"
"int $0x21 \n\t"
: "=a" (ver)
:
: "ax","bx");
#endif
/* EMX set high eax to "em" */
if (ver >> 16 == 0x6d65)
return 1;
else
return 0;
}
void PrintFreeMemInfo()
{
FREEMEMINFO fmi;
FREEMEMINFO *fm = &fmi;
if (is_emx_exe()) {
puts("emx is running; no DPMI services");
return;
}
if (GetFreeMemInfo(fm))
return;
printf("Largest available block : %lu Bytes = %lu KB\n",
fm->LargestFree, fm->LargestFree >> 10);
printf("Number free pages : %4lu = %4lu KB\n"
,fm->MaxUnlockedPages, fm->MaxUnlockedPages * 4);
printf("Number free pages to lock : %4lu = %4lu KB\n"
,fm->MaxLockedPages, fm->MaxLockedPages * 4);
printf("Number pages of linear addr space : %4lu = %4lu KB\n"
,fm->AddressSpacePages, fm->AddressSpacePages * 4);
printf("Number pages not locked : %4lu = %4lu KB\n"
,fm->UnlockedPages, fm->UnlockedPages * 4);
printf("Number pages not used : %4lu = %4lu KB\n"
,fm->UnusedPages, fm->UnusedPages * 4);
printf("Number pages managed by the Dpmi : %4lu = %4lu KB\n"
,fm->PhysicalPages, fm->PhysicalPages * 4);
printf("Number pages free addr space : %4lu = %4lu KB\n"
,fm->FreeAddressSpacePages, fm->FreeAddressSpacePages * 4);
if (fm->PagingFilePages <= 0xFFFFFL)
printf("Number pages in swapfile : %4lu = %4lu KB\n"
,fm->PagingFilePages, fm->PagingFilePages * 4);
else
printf("DPMI host paging partition : %lu Bytes = %lu MB\n"
,fm->PagingFilePages, fm->PagingFilePages >> 20);
}
static void PrintDescriptor(DESCRIPTOR *d)
{
BYTE flag;
if (!(d->access & PRESENT_BIT)) {
printf("Not Present\n");
return;
}
if (d->access & SEGMENT_BIT)/* code or data selector */
printf("Base=%02X%02X%04X Limit=%01X%04X %s DPL=%u %s %s %s %s\n",
d->base_hi, d->base_mi, d->base_lo,
d->lim_hi & LIMIT_HI_MASK, d->lim_lo,
(d->lim_hi & GRANULAR_BIT) ? "Pages" : "Bytes",
(d->access & DPL_MASK) >> 5,
(d->lim_hi & DEFAULT_BIT) ? "32bit" : "16bit",
(d->access & CODE_BIT) ?
(d->access & CONFIRMING_BIT) ? "CONF" : "CODE" :
(d->access & EXPAND_BIT) ? "EXPD" : "DATA",
(d->access & WRITE_BIT) ?
(d->access & CODE_BIT) ? "R" : "W" : "-",
(d->access & ACCESS_BIT) ? "ACC" : " ");
else { /* system selector */
flag = d->access & (BYTE) 7;
switch (flag) {
case 0:
break;
case 1:
printf("TSS%s ", (d->access & 8) ? "386" : "286");
break;
case 2:
printf("LDT ");
break;
case 3:
printf("BUSYTSS%s ", (d->access & 8) ? "386" : "286");
break;
case 4:
printf("CALLGATE%s ", (d->access & 8) ? "386" : "286");
break;
case 5:
printf("TASKGATE ");
break;
case 6:
printf("INT_GATE%s ", (d->access & 8) ? "386" : "286");
break;
case 7:
printf("TRAPGATE%s ", (d->access & 8) ? "386" : "286");
break;
}
if (flag <= 3) {
printf("Base=%02X%02X%04X Limit=%01X%04X DPL=%u\n",
d->base_hi, d->base_mi, d->base_lo,
d->lim_hi & LIMIT_HI_MASK, d->lim_lo,
(d->access & DPL_MASK) >> 5);
} else {
printf("Sel=%04X Offset=%02X%02X%04X DPL=%u\n",
d->base_lo,
d->base_hi, d->lim_hi, d->lim_lo,
(d->access & DPL_MASK) >> 5);
}
} /* else system descriptor */
}
void show_descriptor(int sel, int number)
{
DESCRIPTOR desc;
int i;
if (is_emx_exe()) {
puts("emx is running; no DPMI services");
return;
}
for (i = 1; i <= number; i++) {
printf("sel %X: ", sel);
if (GetDescriptor(sel, &desc)) {
printf("- invalid -\n");
break;
}
PrintDescriptor(&desc);
sel += 8;
}
}